using System;

namespace SystemFrameworks.Util
{
	/// <summary>
	/// Deal with null value
	/// </summary>
	public sealed class NullHelper
	{
		private NullHelper()
		{
		}

		#region Private Field

		// Flag - Type Null Int
		private const			int			NULL_INT		= -1;
		// Flag - Type Null Long 
		private const			long		NULL_LONG		= -1;
		// Flag - Type Null Decimal 
		private const			decimal		NULL_DECIMAL	= -1m;
		// Flag - Type Null DateTime 
		private static readonly	DateTime	NULL_DATE		= new DateTime( 1800, 1, 1 );
		// Flag - Type Null Enum 
		private const			int			NULL_ENUM		= -11;

		#endregion

		#region Public Static Property

		/// <summary>
		/// Special value of null Int
		/// </summary>
		public static int NullInt
		{
			get
			{
				return NULL_INT;
			}
		}

		/// <summary>
		/// Special value of null Long
		/// </summary>
		public static long NullLong
		{
			get
			{
				return NULL_LONG;
			}
		}

		/// <summary>
		/// Special value of null Decimal
		/// </summary>
		public static decimal NullDecimal
		{
			get
			{
				return NULL_DECIMAL;
			}
		}

		/// <summary>
		/// Special value of null DateTime
		/// </summary>
		public static DateTime NullDate
		{
			get
			{
				return NULL_DATE;
			}
		}

		/// <summary>
		/// Special value of null Enum
		/// </summary>
		public static int NullEnum
		{
			get
			{
				return NULL_ENUM;
			}
		}

//		/// <summary>
//		/// Special value of null Enum
//		/// </summary>
//		public static Enum NullEnum( Type enumType )
//		{
//			return Enum.Parse( enumType, Enum.GetName( enumType, NullEnum ) ) ;
//		}

		#endregion

		#region Public Static Method

		#region For Value From SqlReader

		/// <summary>
		/// Get value of Int type
		/// </summary>
		/// <param name="obj"></param>
		/// <returns></returns>
		public static int GetInt32( object obj )
		{
			int result = NULL_INT;

			if ( obj != null && obj != DBNull.Value )
			{
				result = Convert.ToInt32( obj );
			}

			return result;
		}

		/// <summary>
		/// Get value of Long type
		/// </summary>
		/// <param name="obj"></param>
		/// <returns></returns>
		public static long GetLong( object obj )
		{
			long result = NULL_LONG;

			if ( obj != null && obj != DBNull.Value )
			{
				result = Convert.ToInt64( obj );
			}

			return result;
		}

		/// <summary>
		/// Get value of Decimal type
		/// </summary>
		/// <param name="obj"></param>
		/// <returns></returns>
		public static decimal GetDecimal( object obj )
		{
			decimal result = NULL_DECIMAL;

			if ( obj != null && obj != DBNull.Value )
			{
				result = Convert.ToDecimal( obj );
			}

			return result;
		}

		/// <summary>
		/// Get value of Datetime type
		/// </summary>
		/// <param name="obj"></param>
		/// <returns></returns>
		public static DateTime GetDate( object obj )
		{
			DateTime result = NULL_DATE;

			if ( obj != null && obj != DBNull.Value )
			{
				result = Convert.ToDateTime( obj );
			}

			return result;
		}

		/// <summary>
		/// Get value of string type
		/// </summary>
		/// <param name="obj"></param>
		/// <returns></returns>
		public static string GetString( object obj )
		{
			string result = string.Empty;
			
			if ( obj != null && obj != DBNull.Value )
			{
				result = Convert.ToString( obj );
			}

			return result;
		}

		/// <summary>
		/// Get value of bool type
		/// </summary>
		/// <param name="obj"></param>
		/// <returns></returns>
		public static bool GetBool( object obj )
		{
			bool result = false;
			
			if ( obj != null && obj != DBNull.Value )
			{
				result = Convert.ToBoolean( obj );
			}

			return result;
		}

		#endregion		

		#region For Parameter DBNull

		/// <summary>
		/// Set value of Int type
		/// </summary>
		/// <param name="int32"></param>
		/// <returns></returns>
		public static object SetInt32( int int32 )
		{
			if ( int32 == NULL_INT )
			{
				return DBNull.Value;
			}
			else
			{
				return int32;
			}
		}

		/// <summary>
		/// Set value of Long type
		/// </summary>
		/// <param name="int64"></param>
		/// <returns></returns>
		public static object SetLong( long int64 )
		{
			if ( int64 == NULL_LONG )
			{
				return DBNull.Value;
			}
			else
			{
				return int64;
			}
		}

		/// <summary>
		/// Get value of Decimal type
		/// </summary>
		/// <param name="dec"></param>
		/// <returns></returns>
		public static object SetDecimal( decimal dec )
		{
			if ( dec == NULL_DECIMAL )
			{
				return DBNull.Value;
			}
			else
			{
				return dec;
			}
		}

		/// <summary>
		/// Get value of Datetime type
		/// </summary>
		/// <param name="dt"></param>
		/// <returns></returns>
		public static object SetDate( DateTime dt )
		{
			if ( dt == NULL_DATE )
			{
				return DBNull.Value;
			}
			else
			{
				return dt;
			}
		}

		#endregion

		#region Convert To String

		/// <summary>
		/// Convert Int to string
		/// </summary>
		/// <param name="int32"></param>
		/// <returns></returns>
		public static string ToString( int int32 )
		{
			if ( int32 == NULL_INT )
			{
				return string.Empty;
			}
			else
			{
				return int32.ToString();
			}
		}

		/// <summary>
		/// Convert Long to string
		/// </summary>
		/// <param name="int64"></param>
		/// <returns></returns>
		public static string ToString( long int64 )
		{
			if ( int64 == NULL_LONG )
			{
				return string.Empty;
			}
			else
			{
				return int64.ToString();
			}
		}

		/// <summary>
		/// Convert Decimal to string
		/// </summary>
		/// <param name="dec"></param>
		/// <param name="format"></param>
		/// <returns></returns>
		public static string ToString( decimal dec, string format )
		{
			if ( dec == NULL_DECIMAL )
			{
				return string.Empty;
			}
			else
			{
				return dec.ToString( format );
			}
		}

		/// <summary>
		/// Convert Decimal to string
		/// </summary>
		/// <param name="dec"></param>
		/// <param name="format"></param>
		/// <returns></returns>
		public static string ToString( decimal dec )
		{
			if ( dec == NULL_DECIMAL )
			{
				return string.Empty;
			}
			else
			{
				return dec.ToString();
			}
		}

		/// <summary>
		/// Convert DateTime to string
		/// </summary>
		/// <param name="dt"></param>
		/// <param name="format"></param>
		/// <returns></returns>
		public static string ToString( DateTime dt, string format )
		{
			if ( dt == NULL_DATE )
			{
				return string.Empty;
			}
			else
			{
				return dt.ToString( format );
			}
		}

		/// <summary>
		/// Convert DateTime to string
		/// </summary>
		/// <param name="dt"></param>
		/// <param name="format"></param>
		/// <returns></returns>
		public static string ToString( DateTime dt )
		{
			if ( dt == NULL_DATE )
			{
				return string.Empty;
			}
			else
			{
				return dt.ToString();
			}
		}

		#endregion

		#region Parse From String
		

		/// <summary>
		/// Convert String To Int
		/// </summary>
		/// <param name="int32"></param>
		/// <returns></returns>
		public static int ParseInt( string int32 )
		{
			if ( int32.Trim().Length > 0 )
			{
				return int.Parse( int32 );
			}
			else
			{
				return NullHelper.NullInt;
			}
		}

		/// <summary>
		/// Convert String To Long
		/// </summary>
		/// <param name="int64"></param>
		/// <returns></returns>
		public static long ParseLong( string int64 )
		{
			if ( int64.Trim().Length > 0 )
			{
				return long.Parse( int64 );
			}
			else
			{
				return NullHelper.NullLong;
			}
		}
		
		/// <summary>
		/// Convert String To decimal
		/// </summary>
		/// <param name="dec"></param>
		/// <returns></returns>
		public static decimal ParseDecimal( string dec )
		{
			if ( dec.Trim().Length > 0 )
			{
				return decimal.Parse( dec );
			}
			else
			{
				return NullHelper.NullDecimal;
			}
		}

		
		/// <summary>
		/// Convert String To DateTime
		/// </summary>
		/// <param name="dt"></param>
		/// <returns></returns>
		public static DateTime ParseDate( string dt )
		{
			if ( dt.Trim().Length > 0 )
			{
				return DateTime.Parse( dt );
			}
			else
			{
				return NullHelper.NullDate;
			}
		}

		#endregion

		
		#region Check IsNull


		/// <summary>
		/// Check if is NullInt
		/// </summary>
		/// <param name="int32"></param>
		/// <returns></returns>
		public static bool IsNull( int int32 )
		{
			return NullInt == int32;
		}


		/// <summary>
		/// Check if is NullLong
		/// </summary>
		/// <param name="int64"></param>
		/// <returns></returns>
		public static bool IsNull( long int64 )
		{
			return NullLong == int64;
		}

		/// <summary>
		/// Check if is NullDecimal
		/// </summary>
		/// <param name="dec"></param>
		/// <returns></returns>
		public static bool IsNull( decimal dec )
		{
			return NullDecimal == dec;
		}

		/// <summary>
		/// Check if is NullDate
		/// </summary>
		/// <param name="dt"></param>
		/// <returns></returns>
		public static bool IsNull( DateTime dt )
		{
			return NullDate == dt;
		}

		/// <summary>
		/// Check if is NullEnum
		/// </summary>
		/// <param name="enumValue"></param>
		/// <returns></returns>
		public static bool IsNull( Enum enumValue )
		{
			return NullEnum == Convert.ToInt32( enumValue );
		}


		#endregion

		#endregion

	}
}
